net/webrepl: Support LAN interfaces and fix AttributeError on ports without WLAN#1116
net/webrepl: Support LAN interfaces and fix AttributeError on ports without WLAN#1116AsinoEsel wants to merge 1 commit into
Conversation
On ports without network.WLAN (such as the ESP32-P4 port), webrepl crashes on webrepl.start() because network.WLAN is accessed unconditionally in setup_conn(). Add LAN interface support, add try/except around LAN and WLAN access, and add fallback to 0.0.0.0:<port> if no active interface is found. Based on micropython#920 by @Romaric-RILLET. Signed-off-by: AsinoEsel <lerefff@gmail.com>
|
Thanks for the PR! If I read the code correctly, if you have a board that has both LAN and WiFi interfaces available the REPL will bind to the first LAN interface and will leave WiFi interfaces alone. Same thing for WiFi, the old code would bind to all available interfaces, yours stops whenever the first viable interface is found. Maybe that's what somebody may want, but I reckon there ought to be some sort of control on the binding behaviour. How about having an additional optional parameter that indicates which interfaces are enumerated? For now I guess it could be something as simple as this (only for WLAN in this case - completely untested!): diff --git i/micropython/net/webrepl/webrepl.py w/micropython/net/webrepl/webrepl.py
index 00da815..07f9b50 100644
--- i/micropython/net/webrepl/webrepl.py
+++ w/micropython/net/webrepl/webrepl.py
@@ -90,7 +90,11 @@ HTTP/1.0 200 OK\r
cl.close()
-def setup_conn(port, accept_handler):
+BIND_WLAN = const(1)
+BIND_LAN = const(2)
+
+
+def setup_conn(port, accept_handler, bind):
global listen_s
listen_s = socket.socket()
listen_s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
@@ -103,6 +107,8 @@ def setup_conn(port, accept_handler):
if accept_handler:
listen_s.setsockopt(socket.SOL_SOCKET, 20, accept_handler)
for i in (network.WLAN.IF_AP, network.WLAN.IF_STA):
+ if bind & BIND_WLAN == 0:
+ continue
iface = network.WLAN(i)
if iface.active():
print("WebREPL server started on http://%s:%d/" % (iface.ifconfig()[0], port))
@@ -146,7 +152,7 @@ def stop():
listen_s.close()
-def start(port=8266, password=None, accept_handler=accept_conn):
+def start(port=8266, password=None, accept_handler=accept_conn, bind=BIND_WLAN | BIND_LAN):
global static_host
stop()
webrepl_pass = password
@@ -161,7 +167,7 @@ def start(port=8266, password=None, accept_handler=accept_conn):
print("WebREPL is not configured, run 'import webrepl_setup'")
_webrepl.password(webrepl_pass)
- s = setup_conn(port, accept_handler)
+ s = setup_conn(port, accept_handler, (BIND_WLAN | BIND_LAN) if not bind else bind)
if accept_handler is None:
print("Starting webrepl in foreground mode")although things should be optimised to reduce the final size. This also exposes a shortcoming on MicroPython's core side, namely a way to know how many LAN interfaces are available. Technically this could also apply to WiFi if you can have an IP address on 2.4GHz and another on 5GHz. So far there's only one known supported MCU with multi-mode WiFi (ESP32C5) but I bet you can only have one single IP address. |
WebREPL currently does not support LAN interfaces, and raises an AttributeError on webrepl.start() on boards without network.WLAN, such as the ESP32-P4 port. The exception is raised in setup_conn() in line 105:
Steps to reproduce:
import webrepl_setupThis PR adds
I have tested this on an ESP32-P4-ETH board, and a generic ESP32 board. Works as intended.
This issue was raised before in #920 by @Romaric-RILLET, but that attempted fix failed to cover the network.WLAN AttributeError (as it happens outside the try-except block), making it impossible for ethernet-only boards to use WebREPL.